package com.wzcl.app.utils;

import net.minidev.json.JSONUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @program: jpa
 * @description:
 * @author: beingven
 * @create: 2020-11-25 21:20
 **/
public class CollectionUtil {
    /**
     * 对List集合进行分页
     * @param list 需要分页的List集合
     * @param currentPage 当前页
     * @param pageSize 每页条数
     * @param <T> 需要分页的集合类型
     * @return 返回分页后的数据
     */
    public static <T> List<T> getListByPage(List<T> list, Integer currentPage, Integer pageSize){
        List<T> currentPageList = new ArrayList<>();
        if (list != null && list.size() > 0) {
            int currIdx = (currentPage > 1 ? (currentPage - 1) * pageSize : 0);
            for (int i = 0; i < pageSize && i < list.size() - currIdx; i++) {
                T data = list.get(currIdx + i);
                currentPageList.add(data);
            }
        }
        return currentPageList;
    }

    /**
     * 对List集合中的对象进行排序
     * @param list 需要排序的list
     * @param method 需要排序的字段对应的get方法名，例如需要对age进行排序，那么method的值为getAge
     * @param sort 排序方式（asc为升序, desc为降序）
     * @param <T> List中的对象类型
     * @return 返回排序后的list
     */
    public static <T> List<T> getListBySort(List<T> list, String method, String sort) {
        Collections.sort(list, (Comparator<T>) (a, b) -> {
            int ret = 0;
            try{
                Method m1 = ((T) a).getClass().getMethod(method, null);
                Method m2 = ((T)b).getClass().getMethod(method, null);
                if(sort != null && "desc".equals(sort)) {
                    //倒序
                    ret = m2.invoke(((T) b), null).toString().compareTo(m1.invoke(((T) a), null).toString());
                }else if (sort != null && "asc".equals(sort)){
                    //正序
                    ret = m1.invoke(((T) a), null).toString().compareTo(m2.invoke(((T) b), null).toString());
                } else {
                    //默认正序
                    ret = m1.invoke(((T) a), null).toString().compareTo(m2.invoke(((T) b), null).toString());
                }
            }catch(NoSuchMethodException ne){
                System.out.println(ne);
            }catch(IllegalAccessException ie){
                System.out.println(ie);
            }catch(InvocationTargetException it){
                System.out.println(it);
            }
            return ret;
        });
        return list;
    }

    /**
     * 将list中的元素反转（倒序）
     * @param list 需要反转的list
     * @return 返回反转后的list
     */
    public static <T> ArrayList<T> changeListForDesc(ArrayList<T> list){
        ArrayList<T> newList = new ArrayList<>();
        Collections.reverse(list);
        newList.addAll(list);
        return newList;
    }

    /**
     * 判断一个对象是否存在于ArrayList集合中
     * @param list ArrayList集合
     * @param object 对象
     * @param <T> object对象的原本类型
     * @return 返回boolean
     */
    public static <T> Boolean getListIsContainObject(ArrayList<T> list, T object){
        for (int index = 0; index < list.size(); index++) {
            return list.get(index).equals(object);
        }
        return false;
    }

    /**
     * 将list中的元素拼接，并按照partition字符串分隔开，组成一个新的字符串
     * @param list 需要转换为字符串的list
     * @param partition 分隔list元素的字符串
     * @param <T> List中包含的对象类型
     * @return 返回一个拼接后的字符串
     */
    public static <T> String getStringFromList(List<T> list, String  partition){
        String result = "";
        StringBuffer stringBuffer = new StringBuffer(result);
        for (int index = 0; index < list.size(); index++) {
            if (list.size() > 1 && index < list.size() - 1){
                stringBuffer.append(list.get(index)).append(partition);
            }
            if (index == list.size() - 1){
                stringBuffer.append(list.get(index));
                break;
            }
        }
        return stringBuffer.toString();
    }

    /**
     * 将字符串按照partition字符串分隔开，还原为一个新的list
     * @param characterString 需要还原的字符串
     * @param partition 分隔string的字符
     * @return 返回新的List
     */
    public static List<String> getListFromString(String characterString, String partition){
        if (characterString == null || characterString == ""){
            return new ArrayList<>();
        }
        String[] split = characterString.split(partition);
        List<String> list = getListFromArray(split);
        return list;
    }

    /**
     * 数组转List
     * @param array 需要转换的数组
     * @param <T> 数组和List的元素类型
     * @return 返回转换后的List
     */
    public static <T> List<T> getListFromArray(T [] array){
        ArrayList<T> list = new ArrayList<>();
        for (int index = 0; index < array.length; index++) {
            list.add(array[index]);
        }
        return list;
    }

    /**
     * 在一个list中随机取出任意个元素(必须小于等于list长度)，组成一个新的list
     * @param list
     * @param elementNumber
     * @param <T>
     * @return
     */
    public static <T> List<T> getRandomListFromList(List<T> list, Integer elementNumber){
        //TODO 未完成
        //创建一个伪随机数
        Random random = new Random();
        while (true){

        }
    }

    /**
     * 截取一个list中的一部分，生成一个新的list
     * @param list 需要截取的list
     * @param begin 开始索引
     * @param end 结束索引
     * @param <T> list的类型
     * @return 返回截取的list
     */
    public static <T> List<T> getSubList(List<T> list, Integer begin, Integer end){
        List<T> newList = new ArrayList<>();
        for (int index = 0; index < list.size(); index++) {
            if (index >= begin && index <= end){
                newList.add(list.get(index));
            }
        }
        return newList;
    }

    /**
     * 在一个list中随机取出任意个不重复的元素(必须小于等于list长度)，组成一个新的Set不重复集合
     * @param list 需要截取的list
     * @param elementNumber 需要取出的元素个数
     * @param <T> 元素类型
     * @return 返回Set不重复集合
     */
    public static <T> Set<T> getUniqueListFromList(List<T> list, Integer elementNumber){
        if (list.size()<elementNumber){
            throw new RuntimeException("虚拟点赞数不能超出总用户量:"+list.size());
        }
        HashSet<T> hash = new HashSet<>();
        Random random = new Random();
        for (int index = 0; index > -1; index++) {
            int randomNumber = random.nextInt(list.size());
            hash.add(list.get(randomNumber));
            //添加进去后就移除list元素，优化随机效率
            list.remove(randomNumber);
            if (hash.size() > elementNumber-1){
                break;
            }
        }
        return hash;
    }

    /**
     * 将set中的元素拼接，并按照partition字符串分隔开，组成一个新的字符串
     * @param set 需要转换为字符串的set
     * @param partition 分隔set元素的字符串
     * @param <T> set中包含的对象类型
     * @return 返回一个拼接后的字符串
     */
    public static <T> String getStringFromSet(Set<T> set, String  partition){
        ArrayList<T> list = new ArrayList<>(set);
        String result = "";
        StringBuffer stringBuffer = new StringBuffer(result);
        for (int index = 0; index < list.size(); index++) {
            if (set.size() > 1 && index < list.size() - 1){
                stringBuffer.append(list.get(index)).append(partition);
            }else {
                stringBuffer.append(list.get(index));
            }
        }
        return stringBuffer.toString();
    }

    /**
     * 将String类型的List转换为Integer类型
     * @param list 需要转换的list
     * @return 转换后的list
     */
    public static List<Integer> getIntegerFromString(List<String> list){
        ArrayList<Integer> integerList = new ArrayList<>();
        for (int index = 0; index < list.size(); index++) {
            integerList.add(Integer.valueOf(list.get(index)));
        }
        return integerList;
    }

    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("楚留香");
        list.add("陆小凤");
        list.add("西门吹雪");
        list.add("李寻欢");
        list.add("花满楼");
        list.add("燕十三");
        list.add("萧十一郎");
        list.add("花无缺");

        System.out.println(getSubList(list, 2, 5));
    }
}
